
package org.aha.ahaxproject.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.japril.gim.Item;
import org.japril.gim.Items;
import org.japril.gim.sql.SqlItems;
import org.japril.jutil.CharArrayPrintWriter;

//import com.google.appengine.api.rdbms.AppEngineDriver;

@SuppressWarnings("serial")
public final class MyGoogleCloudSqlTestServlet extends HttpServlet 
{
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public MyGoogleCloudSqlTestServlet(){}
  
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException 
  {
    perform(req, res);
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
  {
    perform(req, res);
  }
  
  private void perform(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
  {
    Connection c=null;
    try
    {
      Class<?> dclass=
        Class.forName("com.google.appengine.api.rdbms.AppEngineDriver");
      Driver driver=(Driver)dclass.newInstance();
      DriverManager.registerDriver(driver);
      c=DriverManager.getConnection(
        "jdbc:google:rdbms://ahaspaces:ahaxdb/gim");
      
      Items items=new SqlItems(c);
      
      String reply="";
      
      String oper=req.getParameter("oper");
      if (oper==null)
      {
        reply="missing oper parameter.";
      }
      else if (oper.equals("create-socraton"))
      {
        reply=createSocraton(items, req);
      }
      else if (oper.equals("get-socratons"))
      {
        reply=getSocratons(items);
      }
      else if (oper.equals("get-socraton"))
      {
        reply=getSocraton(items, req);
      }
      else if (oper.equals("add-bison"))
      {
        reply=addBison(items, req);
      }
      else if (oper.equals("get-bisons"))
      {
        reply=getBisons(items, req);
      }
      else
      {
        reply="uknown operation '"+oper+"'";
      }
      
      res.setContentType("text/plain");
      PrintWriter pw=res.getWriter();
      pw.println(reply);
    }
    catch (Exception x)
    {
      IOException iox=new IOException();
      iox.initCause(x);
      throw iox;
    }
    finally
    {
      if (c!=null) try { c.close(); } catch (SQLException _){}
    }
  }
  
  private String getSocraton(Items items, HttpServletRequest req)
  {
    try
    {
      String id=req.getParameter("id");
      if (id==null)
      {
        return "missing parameter id";
      }
      
      Collection<Item> its=items.getItemsWithProperty("id", id, "socraton");
      return socratonsToString(its, items);
    }
    catch (IOException iox)
    {
      return iox.getLocalizedMessage();
    }
  }
  
  private String getBisons(Items items, HttpServletRequest req)
  {
    String id=req.getParameter("id");
    if (id==null)
    {
      return "missing parameter id";
    }
    
    String ctx=req.getParameter("context");
    if (ctx==null)
    {
      return "missing parameter context";
    }
    
    try
    {
      Item s=items.getItemWithProperty("id", id, "socraton");
      if (s==null)
      {
        return "socraton not found";
      } 
      
      String rr="c:"+ctx;
      List<Item> bl=items.getRightItems(s, rr);
      
      String rs=bisonsToString(bl, items);
      CharArrayPrintWriter pw=new CharArrayPrintWriter();
      pw.println(rs);
      pw.println(items);
      return pw.toString();
    }
    catch (IOException iox)
    {
      return iox.getLocalizedMessage();
    }
  }
  
  private String addBison(Items items, HttpServletRequest req)
  {
    String id=req.getParameter("id");
    if (id==null)
    {
      return "missing parameter id";
    }
    
    String bison=req.getParameter("bison");
    if (bison==null)
    {
      return "missing parameter bison";
    }
    
    String ctx=req.getParameter("context");
    if (ctx==null)
    {
      return "missing parameter context";
    }
    
    try
    {
      Item s=items.getItemWithProperty("id", id, "socraton");
      if (s==null)
      {
        return "socraton not found";
      }
      
      Item b=items.create("bison");
      items.setProperty(b, "data", bison);
      
      String lr="c:"+ctx;
      items.createRelation(s, b, lr);
      
      return "created";
    }
    catch (IOException iox)
    {
      return iox.getLocalizedMessage();
    }
  }
  
  private String getSocratons(Items items)
  {
    try
    {
      Collection<Item> its=items.getItems("socraton");
      return socratonsToString(its, items);
    }
    catch (IOException iox)
    {
      return iox.getLocalizedMessage();
    }
  }
  
  private String socratonsToString(Collection<Item> its, Items items)
    throws IOException
  {
    CharArrayPrintWriter capw=new CharArrayPrintWriter();
    int n=its.size();
    capw.println("number of socratons: "+n);
    
    StringBuilder sb=new StringBuilder();
    for (Item item : its)
    {
      sb.setLength(0);
      String sid=items.getStringProperty(item, "id");
      sb.append("assigned key=").append(item.getId()).append(" id=")
        .append(sid);
      capw.println(sb);
    }
    return capw.toString();
  }
  
  private String bisonsToString(Collection<Item> bl, Items items)
    throws IOException
  {
    CharArrayPrintWriter capw=new CharArrayPrintWriter();
    int n=bl.size();
    capw.println("number of bisons: "+n);
      
    StringBuilder sb=new StringBuilder();
    for (Item item : bl)
    {
      sb.setLength(0);
      String data=items.getStringProperty(item, "data");
      sb.append("assigned key=").append(item.getId()).append(" data=")
        .append(data);
      capw.println(sb);
    }
    return capw.toString();
  }
  
  private String createSocraton(Items items, HttpServletRequest req)
  {
    try
    {
      String id=req.getParameter("id");
      Item socraton=items.create("socraton");
      id=(id==null) ? Integer.toString(socraton.getId()) : id;
      
      items.setProperty(socraton, "id", id);
      
      StringBuilder sb=new StringBuilder();
      sb.append("created socraton: assigned key=").append(socraton.getId())
        .append(" with id=").append(id);
      return sb.toString();
    }
    catch (IOException iox)
    {
      return iox.getLocalizedMessage();
    }
  }
  
}
